﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
//using System.Data.SqlClient;
using System.Data;
using System.Data.Common;
using System.Reflection;
using System.Data.Linq.Mapping;
using System.ServiceModel;

namespace CP.DBService
{
    public class DBLinq<T>
    {
        private static DBLinq<T> instance;
        private DBHelper helper;
        private SqlSegmentBuilder<T> sqlBuilder;

        public static DBLinq<T> CreateInstance()
        {
            if (instance == null)
            {
                instance = new DBLinq<T>();
                instance.helper = DBHelper.CreateInstance();
                instance.sqlBuilder = new SqlSegmentBuilder<T>();
            }
            return instance;
        }

        public IList<T> GetEntities()
        {

            sqlBuilder.Clear();
            string sql = sqlBuilder.BuildSelect().SelectCommandText;

            return helper.ExecuteObject<T>(sql);
        }

        //where筛选语句传入
        public IList<T> GetEntitiesByParameters(string parameters)
        {

            sqlBuilder.Clear();
            string sql = sqlBuilder.BuildSelect().SelectCommandText;
            if (!string.IsNullOrEmpty(parameters))
            {
                if (parameters.TrimStart().StartsWith("and ", StringComparison.OrdinalIgnoreCase) ||
                    parameters.TrimStart().StartsWith("order by ", StringComparison.OrdinalIgnoreCase)
                    )
                    sql += " where 1=1 " + parameters;
                else
                    sql += " where 1=1 and " + parameters;
            } 

            return helper.ExecuteObject<T>(sql);

        }

        //where筛选语句拼接
        public T GetEntityByID<PKType>(PKType entityID)
        {
            sqlBuilder.Clear();
            string sql = sqlBuilder.BuildSelect().BuildWherePK(entityID).SelectCommandText;
            var result = helper.ExecuteObject<T>(sql);
            if (result != null && result.Count > 0)
                return result[0];
            else
                return default(T);
        }

        public void InsertEntity(T entity)
        {
            if (entity == null) return;
            sqlBuilder.Clear();
            DbCommand command = helper.CreateCommand();
            sqlBuilder.BuildInsertCommand(entity, command);
            command.ExecuteNonQuery();

            helper.CloseConnection(command.Connection);

        }

        public void UpdateEntity(T entity)
        {
            if (entity == null) return;

            sqlBuilder.Clear();
            DbCommand command = helper.CreateCommand();
            sqlBuilder.BuildUpdateCommand(entity, command);

            try
            {
                command.ExecuteNonQuery();
            }
            finally
            {
                helper.CloseConnection(command.Connection);
            }

        }

        public void DeleteEntityByID<PKType>(PKType entityID)
        {
            sqlBuilder.Clear();

            DbCommand command = helper.CreateCommand();
            sqlBuilder.BuildeDeleteCommandByPK<PKType>(entityID, command);

            try
            {

                command.ExecuteNonQuery();
            }
            finally
            {
                helper.CloseConnection(command.Connection);
            }

        }

        public void DeleteEntity(T entity)
        {
            if (entity == null) return;
            sqlBuilder.Clear();
            DbCommand command = helper.CreateCommand();
            sqlBuilder.BuildDeleteCommand(entity, command);

            try
            {
                command.ExecuteNonQuery();
            }
            finally
            {
                helper.CloseConnection(command.Connection);
            }
        }

        public void InsertEntities(IList<T> entities)
        {
            foreach (var entity in entities)
            {
                InsertEntity(entity);
            }
        }

        public void UpdateEntities(IList<T> entities)
        {
            try
            {
                helper.BeginTransaction();
                foreach (var entity in entities)
                {
                    UpdateEntity(entity);
                }
                helper.Commit();
            }
            catch (Exception e)
            {
                helper.Rollback();
                throw e;
            }
        }

        public void DeleteEntities(IList<T> entities)
        {
            foreach (var entity in entities)
            {
                DeleteEntity(entity);
            }
        }

    }
}
